package com.cq.hd.member.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cq.hd.common.enums.biz.BusinessPointsMallProductTypeEnum;
import com.cq.hd.common.enums.biz.BusinessPointsMallStateEnum;
import com.cq.hd.common.enums.biz.OwnStateEnum;
import com.cq.hd.common.pagination.Page;
import com.cq.hd.common.response.Throw;
import com.cq.hd.common.utils.BeanUtils;
import com.cq.hd.common.utils.StringUtils;
import com.cq.hd.member.api.dto.*;
import com.cq.hd.member.api.vo.BusinessMerchantVo;
import com.cq.hd.member.api.vo.BusinessPointsMallProductDetailVo;
import com.cq.hd.member.api.vo.BusinessPointsMallProductPageVo;
import com.cq.hd.member.api.vo.BusinessPointsMallProductVo;
import com.cq.hd.member.mapper.*;
import com.cq.hd.member.po.TbBusinessPo;
import com.cq.hd.member.po.TbBusinessPointsMallProductPo;
import com.cq.hd.member.po.TbUserPointsAccountPo;
import com.cq.hd.member.service.TbBusinessMerchantService;
import com.cq.hd.member.service.TbBusinessPointsMallProductService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 商家表 服务实现类
 * </p>
 *
 * @author mYunYu
 * @since 2023-11-21
 */
@Slf4j
@Service
public class TbBusinessPointsMallProductServiceImpl extends ServiceImpl<TbBusinessPointsMallProductMapper, TbBusinessPointsMallProductPo> implements TbBusinessPointsMallProductService {
    @Autowired
    private TbBusinessMapper tbBusinessMapper;

    @Autowired
    private TbUserPointsAccountMapper tbUserPointsAccountMapper;

    @Autowired
    private TbBusinessPointsMallStatMapper tbBusinessPointsMallStatMapper;

    @Autowired
    private TbBusinessMerchantService businessMerchantService;

    @Override
    public List<BusinessPointsMallProductVo> getProductList(BusinessPointsMallProductListDto productListDto) {
        if (productListDto.getViewType() == 2) {
            // 别人查看，先判断商家是否开启了积分商城
            TbBusinessPo businessPo = tbBusinessMapper.selectById(productListDto.getBusinessId());
            if (businessPo == null || businessPo.getDelState() != 0) {
                Throw.isBusinessException("商家不存在");
            }
            Integer state = businessPo.getPointsMallState();
            if (state == null || !state.equals(BusinessPointsMallStateEnum.OPEN.getValue())) {
                return Collections.emptyList();
            }
        }
        return baseMapper.getProductList(productListDto);
    }

    @Override
    public BusinessPointsMallProductDetailVo productDetail(Long id, Long userId) {
        TbBusinessPointsMallProductPo o = baseMapper.selectById(id);
        if (o == null || o.getDelState() != 0) {
            Throw.isBusinessException("商品不存在");
        }
        BusinessPointsMallProductDetailVo vo = new BusinessPointsMallProductDetailVo();
        BeanUtils.copyProperties(o, vo);

        TbUserPointsAccountPo accountPo = tbUserPointsAccountMapper.getAccount(vo.getBusinessId(), userId);
        if (accountPo != null) {
            vo.setRemainPoint(accountPo.getRemainPoint());
        }
        return vo;
    }

    @Override
    public Page<BusinessPointsMallProductPageVo> adminPageProducts(BusinessPointsMallProductPageDto businessPointsMallProductPageDto) {
        PageHelper.startPage(businessPointsMallProductPageDto.getPageNum(), businessPointsMallProductPageDto.getPageSize());
        List<BusinessPointsMallProductPageVo> pageVos = baseMapper.adminPageProducts(businessPointsMallProductPageDto);
        PageInfo<BusinessPointsMallProductPageVo> pageInfo = new PageInfo<>(pageVos);
        return Page.newPageWithAllFields(pageInfo.getList(), pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal(), pageInfo.getPages());
    }

    private void commonCheck(BusinessPointsMallProductDto businessPointsMallProductDto) {
        BigDecimal amount = businessPointsMallProductDto.getAmount();
        Integer totalNum = businessPointsMallProductDto.getTotalNum();
        Integer dayLimit = businessPointsMallProductDto.getDayLimit();
        BigDecimal requiredPoints = businessPointsMallProductDto.getRequiredPoints();

        BigDecimal maxAmount = BigDecimal.valueOf(1000000); // 金额最多 1000000
        int maxNum = 100000; // 上架数量：正整数，不超100000
        int maxDay = 365; // 使用期限：正整数，不超365天
        BigDecimal maxScore = BigDecimal.valueOf(1000000); // 兑换积分：正整数，不超过1000000
        String amountName = "优惠金额";
        if (businessPointsMallProductDto.getProductType().equals(BusinessPointsMallProductTypeEnum.GOODS.getValue())) {
            amountName = "商品结算价格";
        }

        if (amount == null || amount.compareTo(BigDecimal.ZERO) < 0) {
            businessPointsMallProductDto.setAmount(BigDecimal.ZERO);
//            Throw.isBusinessException("请填写" + amountName);
        }
        if (amount.compareTo(maxAmount) > 0) {
            Throw.isBusinessException(amountName + "不能超过" + maxAmount);
        }

        if (totalNum == null || totalNum <= 0) {
            Throw.isBusinessException("请填写上架数量");
        }
        if (totalNum > maxNum) {
            Throw.isBusinessException("上架数量不能超过" + maxNum);
        }

        if (dayLimit == null || dayLimit <= 0) {
            Throw.isBusinessException("请输入使用期限");
        }
        if (dayLimit > maxDay) {
            Throw.isBusinessException("使用期限不能超过" + maxDay + "天");
        }

        if (requiredPoints == null || requiredPoints.compareTo(BigDecimal.ZERO) <= 0) {
            Throw.isBusinessException("请输入兑换所需积分");
        }
        if (requiredPoints.compareTo(maxScore) > 0) {
            Throw.isBusinessException("兑换所需积分不能超过" + maxScore);
        }
    }

    @Override
    public Boolean saveCoupon(BusinessPointsMallCouponDto businessPointsMallCouponDto) {
        BigDecimal fullAmount = businessPointsMallCouponDto.getFullAmount();
        if (fullAmount == null || fullAmount.compareTo(BigDecimal.ZERO) < 0) {
            Throw.isBusinessException("请填写门槛金额");
        }
        if (fullAmount.compareTo(BigDecimal.valueOf(1000000)) > 0) {
            Throw.isBusinessException("门槛金额不能超过" + 1000000);
        }

        BusinessPointsMallProductDto productDto = new BusinessPointsMallProductDto();
        BeanUtils.copyProperties(businessPointsMallCouponDto, productDto);
        productDto.setProductType(BusinessPointsMallProductTypeEnum.COUPON.getValue());
        commonCheck(productDto);

        String amount = productDto.getAmount().stripTrailingZeros().toPlainString();
        String goodsName = amount + "元无门槛券";
        if (fullAmount.compareTo(BigDecimal.ZERO) > 0) {
            goodsName = "满" + fullAmount.stripTrailingZeros().toPlainString() + "减" + amount + "优惠券";
        }
        productDto.setGoodsName(goodsName);

        return saveOrUpdateData(productDto);
    }

    @Override
    public Boolean saveGoods(BusinessPointsMallGoodsDto businessPointsMallGoodsDto) {
        String goodsName = businessPointsMallGoodsDto.getGoodsName();
        if (StringUtils.isBlank(goodsName)) {
            Throw.isBusinessException("请填写商品名称");
        }
        if (goodsName.length() < 4 || goodsName.length() > 30) {
            Throw.isBusinessException("商品名称：4-30字");
        }
        List<String> goodsImages = businessPointsMallGoodsDto.getGoodsImages();
        if (goodsImages == null || goodsImages.isEmpty()) {
            Throw.isBusinessException("请上传商品图片");
        }
        if (goodsImages.size() > 6) {
            Throw.isBusinessException("商品图片最多上传6张");
        }

        List<Long> merchantIds = businessPointsMallGoodsDto.getMerchantIds();
        if (merchantIds == null) {
            merchantIds = new ArrayList<>();
        }
        if (merchantIds.isEmpty()) {
            // 查询商家数据，获取商家自有商户id
            BusinessMerchantVo businessMerchantVo = businessMerchantService.getOwnByBusinessId(businessPointsMallGoodsDto.getBusinessId(), OwnStateEnum.YES.getValue());
            Long merchantId = businessMerchantVo.getMerchantId();
            merchantIds.add(merchantId);
        }
        // 商户数量限制
        TbBusinessPo businessPo = tbBusinessMapper.selectById(businessPointsMallGoodsDto.getBusinessId());
        // 仅限x个商户参与
        Integer maxMerchantCount = businessPo.getSingleActiveMerchantCount();
        if (maxMerchantCount != null && maxMerchantCount < merchantIds.size()) {
            Throw.isBusinessException("仅限" + maxMerchantCount + "个商户参与");
        }

        String details = businessPointsMallGoodsDto.getDetails();
        if (StringUtils.isBlank(details)) {
            Throw.isBusinessException("请输入商品详情及兑换说明");
        }

        BusinessPointsMallProductDto productDto = new BusinessPointsMallProductDto();
        BeanUtils.copyProperties(businessPointsMallGoodsDto, productDto);
        productDto.setProductType(BusinessPointsMallProductTypeEnum.GOODS.getValue());
        commonCheck(productDto);

        return saveOrUpdateData(productDto);
    }

    private Boolean saveOrUpdateData(BusinessPointsMallProductDto productDto) {
        Long id = productDto.getId();
        Long businessId = productDto.getBusinessId();
        LocalDateTime now = LocalDateTime.now();
        if (id != null && id > 0) {
            TbBusinessPointsMallProductPo po = getById(id);
            if (po == null || !po.getBusinessId().equals(businessId)) {
                Throw.isBusinessException("记录不存在");
            }
            int usedNum = po.getUsedNum();
            if (productDto.getTotalNum() < usedNum) {
                Throw.isBusinessException("上架数量不能小于已领取数量：" + usedNum);
            }
            BeanUtils.copyProperties(productDto, po);
            po.setRemainNum(po.getTotalNum() - usedNum);
            po.setUpdateTime(now);
            return updateById(po);
        }

        TbBusinessPointsMallProductPo po = new TbBusinessPointsMallProductPo();
        BeanUtils.copyProperties(productDto, po);
        po.setRemainNum(po.getTotalNum());
        po.setCreateTime(now);
        po.setUpdateTime(now);
        Boolean res = save(po);
        if (res) {
            tbBusinessPointsMallStatMapper.updateProductNum(businessId, 1);
        }
        return res;
    }

    // 删除优惠券、核销商品
    @Override
    public Boolean removeProduct(Long id, Long businessId) {
        TbBusinessPointsMallProductPo po = baseMapper.selectById(id);
        if (po == null || po.getDelState() != 0 || !po.getBusinessId().equals(businessId)) {
            return true;
        }
        po.setDelState(1);
        po.setUpdateTime(LocalDateTime.now());
        Boolean res = updateById(po);
        if (res) {
            tbBusinessPointsMallStatMapper.updateProductNum(businessId, -1);
        }
        return res;
    }
}
